package pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.factory;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.jdom.Element;

import pe.com.pgn.consolidadorventas.servidorcentral.util.ArchivosUtil;
import pe.com.pgn.consolidadorventas.servidorcentral.util.Base64Util;
import pe.com.pgn.consolidadorventas.servidorcentral.util.Constantes;
import pe.com.pgn.consolidadorventas.servidorcentral.util.LoggerUtil;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.GlpRptaConsultaVenta;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.glp.GlpRegistroVenta;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.glp.GlpRegistroVentaDetalle;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.glp.GlpRegistroVentaDocAnti;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.glp.GlpRegistroVentaOpBonus;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.glp.GlpRegistroVentaPrincipal;
import pe.com.pgn.consolidadorventas.servidorcentral.ws.domain.glp.GlpRegistroVentaSalesCard;

public class GlpXmlToObjectFactory {

	static Logger logger = Logger.getLogger(GlpXmlToObjectFactory.class);

	public static void parsearArchivoZipeado(String rutaZip,String rutaDescomprimido,Element raiz,GlpRptaConsultaVenta resultadoOperacion){
		String hash = raiz.getChildText("contenido");
		byte[] buffer = Base64Util.convertirStringBase64Bytes(hash);
		ArchivosUtil.crearArchivoBinario(rutaZip,buffer);
		if(ArchivosUtil.verificarExistenciaArchivo(rutaZip)){
			ArchivosUtil.descomprimirArchivo(rutaZip,rutaDescomprimido);
			if(ArchivosUtil.verificarExistenciaArchivo(rutaDescomprimido)){
				
				List<String> lineas = ArchivosUtil.cargarArchivo(rutaDescomprimido, Constantes.COD_UNICODE);
		    	
		    	int i = 0;
				int tipoLinea = 0;
				int dim = lineas.size();
				
				//Listado de las ventas
				List<GlpRegistroVenta> listadoVentas = new ArrayList<GlpRegistroVenta>();
				
				GlpRegistroVenta registroVenta = null;
				
				GlpRegistroVentaPrincipal principal = null;
				List<GlpRegistroVentaDetalle> listaDetalles = null;
				List<GlpRegistroVentaSalesCard> listaSalesCard = null;
				List<GlpRegistroVentaDocAnti> listaDocAnti = null;
				List<GlpRegistroVentaOpBonus> listaOpBonus = null;
				
				while(i < dim){
					
					String cadena = lineas.get(i);
					tipoLinea = getTipoLinea(cadena);					
					
					//Seccionamos la cadena
					String valores[]=cadena.split("\\|");
					
					if(tipoLinea == Constantes.GLP_LINEA_RESUMEN){
						GlpParserLinea.asignarValoresVentas(resultadoOperacion, valores);
					}
					
					switch(tipoLinea){
						case 1:{
							
							//Si ya se ha creado un nodo de la informacion anterior se agrega a la raiz
							if(registroVenta!=null){
								//Armamos el registro completo
								
								//Cerramos el recorrido del fichero
								//Agregamos los detalles
								if(listaDetalles!=null){ registroVenta.setDetalles(listaDetalles); }
								
								//Agregamos los salescards
								if(listaSalesCard!=null){ registroVenta.setSalesCards(listaSalesCard); }
								
								//Agregamos los opDocAntis
								if(listaDocAnti!=null){ registroVenta.setDocAntis(listaDocAnti); }
								
								//Agregamos los opBonus
								if(listaOpBonus!=null){ registroVenta.setOpBonus(listaOpBonus); }
										
								listadoVentas.add(registroVenta);
								
								registroVenta = null;
								principal = null;
								listaDetalles = null;
								listaSalesCard = null;
								listaDocAnti = null;
								listaOpBonus = null;
								
							}
							
							//El nodo esta nulo , recien empezamos a crear
							//Creamos el nodo raiz
							registroVenta = new GlpRegistroVenta();
							principal = GlpParserLinea.parsearLineaPrincipal(valores);
							registroVenta.setPrincipal(principal);
									
							break;
						}
						
						
						case 2:{
							if(listaDetalles==null){
								listaDetalles = new ArrayList<GlpRegistroVentaDetalle>();
							}
							GlpRegistroVentaDetalle detalle = GlpParserLinea.parsearLineaDetalle(valores);
							if(detalle!=null){
								listaDetalles.add(detalle);
							}
							break;
						}
						
						case 3:{
							if(listaSalesCard==null){
								listaSalesCard = new ArrayList<GlpRegistroVentaSalesCard>();
							}
							GlpRegistroVentaSalesCard salesCard = GlpParserLinea.parsearLineaSalesCard(valores);
							if(salesCard!=null){
								listaSalesCard.add(salesCard);
							}
							break;
						}
						
						case 4:{
							if(listaDocAnti==null){
								listaDocAnti = new ArrayList<GlpRegistroVentaDocAnti>();
							}
							GlpRegistroVentaDocAnti docAnti = GlpParserLinea.parsearLineaDocAnti(valores);
							if(docAnti!=null){
								listaDocAnti.add(docAnti);
							}
							break;
						}
						
						case 5:{
							if(listaOpBonus==null){
								listaOpBonus = new ArrayList<GlpRegistroVentaOpBonus>();
							}
							GlpRegistroVentaOpBonus opBonus = GlpParserLinea.parsearLineaOpBonus(valores);
							if(opBonus!=null){
								listaOpBonus.add(opBonus);
							}
							break;
						}
						
						case 6:{
							//Cerramos el recorrido del fichero
							//Agregamos los detalles
							if(listaDetalles!=null){ registroVenta.setDetalles(listaDetalles); }
							
							//Agregamos los salescards
							if(listaSalesCard!=null){ registroVenta.setSalesCards(listaSalesCard); }
							
							//Agregamos los opDocAntis
							if(listaDocAnti!=null){ registroVenta.setDocAntis(listaDocAnti); }
							
							//Agregamos los opBonus
							if(listaOpBonus!=null){ registroVenta.setOpBonus(listaOpBonus); }
							
							listadoVentas.add(registroVenta);
							break;
						}

					}	
					
					i++;
				}
				
				resultadoOperacion.setListaVentas(listadoVentas);
				
				if(!ArchivosUtil.borrarArchivo(rutaZip)){
					LoggerUtil.error(logger, "No se pudo borrar el archivo : "+rutaZip);
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void parsearXmlDirecto(String rutaGuardarArchivo,Element raiz,GlpRptaConsultaVenta resultadoOperacion){
    	//Tomamos todas las lineas
    	List<Element> lineas = (List<Element>)raiz.getChildren("linea");
    	
    	//Lista de lineas para guardar el archivo recibido en un historico
    	List<String> lineasArchivo = new ArrayList<String>();
    	
    	int i = 0;
		int tipoLinea = 0;
		int dim = lineas.size();
		LoggerUtil.debug(logger,"Parseo xml directo");
		
		//Listado de las ventas
		List<GlpRegistroVenta> listadoVentas = new ArrayList<GlpRegistroVenta>();
		
		GlpRegistroVenta registroVenta = null;
		
		GlpRegistroVentaPrincipal principal = null;
		List<GlpRegistroVentaDetalle> listaDetalles = null;
		List<GlpRegistroVentaSalesCard> listaSalesCard = null;
		List<GlpRegistroVentaDocAnti> listaDocAnti = null;
		List<GlpRegistroVentaOpBonus> listaOpBonus = null;
		
		while(i < dim){
			
			String cadena = lineas.get(i).getText();
			tipoLinea = getTipoLinea(cadena);
			lineasArchivo.add(cadena);
			
			
			//Seccionamos la cadena
			String valores[]=cadena.split("\\|");
			
			if(tipoLinea == Constantes.GLP_LINEA_RESUMEN){
				GlpParserLinea.asignarValoresVentas(resultadoOperacion, valores);
			}
			
			switch(tipoLinea){
				case 1:{
					
					//Si ya se ha creado un nodo de la informacion anterior se agrega a la raiz
					if(registroVenta!=null){
						//Armamos el registro completo
						
						//Cerramos el recorrido del fichero
						//Agregamos los detalles
						if(listaDetalles!=null){ registroVenta.setDetalles(listaDetalles); }
						
						//Agregamos los salescards
						if(listaSalesCard!=null){ registroVenta.setSalesCards(listaSalesCard); }
						
						//Agregamos los opDocAntis
						if(listaDocAnti!=null){ registroVenta.setDocAntis(listaDocAnti); }
						
						//Agregamos los opBonus
						if(listaOpBonus!=null){ registroVenta.setOpBonus(listaOpBonus); }
								
						listadoVentas.add(registroVenta);
						
						registroVenta = null;
						principal = null;
						listaDetalles = null;
						listaSalesCard = null;
						listaDocAnti = null;
						listaOpBonus = null;
						
					}
					
					//El nodo esta nulo , recien empezamos a crear
					//Creamos el nodo raiz
					registroVenta = new GlpRegistroVenta();
					principal = GlpParserLinea.parsearLineaPrincipal(valores);
					registroVenta.setPrincipal(principal);
							
					break;
				}
				
				
				case 2:{
					if(listaDetalles==null){
						listaDetalles = new ArrayList<GlpRegistroVentaDetalle>();
					}
					GlpRegistroVentaDetalle detalle = GlpParserLinea.parsearLineaDetalle(valores);
					if(detalle!=null){
						listaDetalles.add(detalle);
					}
					break;
				}
				
				case 3:{
					if(listaSalesCard==null){
						listaSalesCard = new ArrayList<GlpRegistroVentaSalesCard>();
					}
					GlpRegistroVentaSalesCard salesCard = GlpParserLinea.parsearLineaSalesCard(valores);
					if(salesCard!=null){
						listaSalesCard.add(salesCard);
					}
					break;
				}
				
				case 4:{
					if(listaDocAnti==null){
						listaDocAnti = new ArrayList<GlpRegistroVentaDocAnti>();
					}
					GlpRegistroVentaDocAnti docAnti = GlpParserLinea.parsearLineaDocAnti(valores);
					if(docAnti!=null){
						listaDocAnti.add(docAnti);
					}
					break;
				}
				
				case 5:{
					if(listaOpBonus==null){
						listaOpBonus = new ArrayList<GlpRegistroVentaOpBonus>();
					}
					GlpRegistroVentaOpBonus opBonus = GlpParserLinea.parsearLineaOpBonus(valores);
					if(opBonus!=null){
						listaOpBonus.add(opBonus);
					}
					break;
				}
				
				case 6:{
					//Cerramos el recorrido del fichero
					//Agregamos los detalles
					if(listaDetalles!=null){ registroVenta.setDetalles(listaDetalles); }
					
					//Agregamos los salescards
					if(listaSalesCard!=null){ registroVenta.setSalesCards(listaSalesCard); }
					
					//Agregamos los opDocAntis
					if(listaDocAnti!=null){ registroVenta.setDocAntis(listaDocAnti); }
					
					//Agregamos los opBonus
					if(listaOpBonus!=null){ registroVenta.setOpBonus(listaOpBonus); }
					
					listadoVentas.add(registroVenta);
					break;
				}

			}	
			
			i++;
		}
		
		//Si la fecha no esta vacia la guardamos
		if(!rutaGuardarArchivo.equals("")){
			boolean sw =  ArchivosUtil.guardarArchivo(rutaGuardarArchivo, lineasArchivo);
			if(sw==false){
				LoggerUtil.error(logger,"No se pudo guardar el archivo "+rutaGuardarArchivo);
			}
		}
		resultadoOperacion.setListaVentas(listadoVentas);
    	
    }
    
	@SuppressWarnings("unchecked")
	public static void parsearXmlDetallado(Element raiz,GlpRptaConsultaVenta resultadoOperacion){
    	//La llamada fue correcta , capturamos todos los resultados
	   	//Capturamos todos los resultados
		LoggerUtil.debug(logger,"Parseo xml detallado");

		int cantidadVentas = Integer.parseInt(raiz.getAttributeValue("cantidadVentas")); 
	   	resultadoOperacion.setCantidadVentas(cantidadVentas);
	   	resultadoOperacion.setVentaTotal(raiz.getAttributeValue("ventaTotal"));


		List<GlpRegistroVenta> listaVentas = new ArrayList<GlpRegistroVenta>();
   	 	List<Element> elementos = (List<Element>)raiz.getChildren("registroVenta");
        
        int limite = elementos.size();
        for(int i=0;i<limite;i++){
       	
        	GlpRegistroVenta registroVenta = new GlpRegistroVenta();  
        	Element nodoRegistroVenta = elementos.get(i);
        	
        	//Sacamos los datos
        	Element nodoDatoPrincipal = nodoRegistroVenta.getChild("principal");
        	Element nodoDetalles = nodoRegistroVenta.getChild("detalles");
        	
        	/*
        	Element nodoSalesCards = nodoRegistroVenta.getChild("salesCards");
        	Element nodoOpDocAntis = nodoRegistroVenta.getChild("opDocAntis");
        	Element nodoOpBonus = nodoRegistroVenta.getChild("opBonus");
        	*/
        	
        	//Convertimos el registro principal
        	GlpRegistroVentaPrincipal principal = (GlpRegistroVentaPrincipal)GlpXmlToObjectFactory.convertirNodoRegistro(nodoDatoPrincipal);
        	
        	//Convertimos los detalles     	
        	List<GlpRegistroVentaDetalle> detalles = null;
       
        	if(nodoDetalles!=null){
        		detalles = new ArrayList<GlpRegistroVentaDetalle>();
            	List<Element> listaDetalles = (List<Element>)nodoDetalles.getChildren("regDetalle");
            	for(int j = 0;j<listaDetalles.size();j++){
            		GlpRegistroVentaDetalle aux = (GlpRegistroVentaDetalle)GlpXmlToObjectFactory.convertirNodoRegistro(listaDetalles.get(j));
            		detalles.add(aux);
            	}
        	}
        	
        	registroVenta.setPrincipal(principal);
        	registroVenta.setDetalles(detalles); 	
        	listaVentas.add(registroVenta);
        	
        }            
        resultadoOperacion.setListaVentas(listaVentas);
    }
	
	public static int getTipoLinea(String valor) {
		int tipoLinea = 0;
		try{
			tipoLinea = Integer.parseInt(valor.substring(1,2));
		}catch(NumberFormatException nfe){
			logger.error(nfe.getMessage());
			tipoLinea = 0;
		}
		return tipoLinea;
	}
	
	public static Object convertirNodoRegistro(Element nodo) {
		
		Object rpta = null;
		String tipoNodo = nodo.getName();
		if(tipoNodo.equals("principal")){
			rpta = convertirNodoXmlRegistroVentaPrincipal(nodo);
		}
		
		if(tipoNodo.equals("regDetalle")){
			rpta = convertirNodoXmlRegistroVentaDetalle(nodo);
		}
	
		return rpta;
	}
	
	private static GlpRegistroVentaPrincipal convertirNodoXmlRegistroVentaPrincipal(Element nodo){
		
		GlpRegistroVentaPrincipal registro = new GlpRegistroVentaPrincipal();
		
		registro.setDocTypeId(nodo.getAttributeValue("docTypeId"));	
     	registro.setNbrDocument(nodo.getAttributeValue("nbrDocument"));
		registro.setSiteId(nodo.getAttributeValue("siteId"));
		
		registro.setTypePaymentId(nodo.getChildText("typePaymentId"));
		registro.setStkInventory(nodo.getChildText("stkInventory"));
		registro.setDocStatusId(nodo.getChildText("docStatusId"));
		registro.setTermId(nodo.getChildText("termId"));
		registro.setSalesPerId(nodo.getChildText("salesPerId"));
		registro.setUserId(nodo.getChildText("userId"));
		registro.setDateDoc(nodo.getChildText("dateDoc"));
		registro.setDateProceSales(nodo.getChildText("dateProceSales"));
		registro.setPerPost(nodo.getChildText("perPost"));	
		registro.setTotalPen(nodo.getChildText("totalPen"));
		registro.setSubTotalPen(nodo.getChildText("subTotalPen"));
		registro.setTaxIgvPen(nodo.getChildText("taxIgvPen"));	
		registro.setTotCashPen(nodo.getChildText("totCashPen"));
		
		registro.setCustIdss(nodo.getChildText("custIdss"));
		
		registro.setTaxRegnBr(nodo.getChildText("taxRegnBr"));
		registro.setPlaca(nodo.getChildText("placa"));
		registro.setNbrBonus(nodo.getChildText("nbrBonus"));	
		registro.setSalesPoint(nodo.getChildText("salesPoint"));
		registro.setKilometraje(nodo.getChildText("kilometraje"));
		registro.setBusinessType(nodo.getChildText("businessType"));
		registro.setUser9(nodo.getChildText("user9"));
		registro.setCustName(nodo.getChildText("custName"));
		registro.setFilaVenDet(nodo.getChildText("filaVenDet"));
		registro.setFilaVenSal(nodo.getChildText("filaVenSal"));
		registro.setFilaVenDoc(nodo.getChildText("filaVenDoc"));
		registro.setFilaVenBon(nodo.getChildText("filaVenBon"));
		registro.setChkVenDet(nodo.getChildText("chkVenDet"));
		registro.setChkVenSal(nodo.getChildText("chkVenSal"));
		
		return registro;
	}
		
	private static GlpRegistroVentaDetalle convertirNodoXmlRegistroVentaDetalle(Element nodo){
		GlpRegistroVentaDetalle detalle = new GlpRegistroVentaDetalle();
		
     	detalle.setDocTypeId(nodo.getAttributeValue("docTypeId"));
     	detalle.setNbrDocument(nodo.getAttributeValue("nbrDocument"));
     	detalle.setSiteId(nodo.getAttributeValue("siteId"));
     	detalle.setSequence(nodo.getAttributeValue("sequence"));
     	detalle.setInvtidsku(nodo.getAttributeValue("invtidsku"));
     	detalle.setDocStatusId(nodo.getAttributeValue("docStatusId"));
     	
     	detalle.setDateDoc(nodo.getChildText("dateDoc"));
     	detalle.setDateProceSales(nodo.getChildText("dateProceSales"));
     	detalle.setPerPost(nodo.getChildText("perPost"));
     	
     	detalle.setNbrTurn(nodo.getChildText("nbrTurn"));
     	detalle.setNbrSide(nodo.getChildText("nbrSide"));
     	detalle.setPorcentTaxIgv(nodo.getChildText("porcentTaxIgv"));
     	detalle.setTotalPen(nodo.getChildText("totalPen"));
     	detalle.setTaxPen(nodo.getChildText("taxPen"));
     	detalle.setStkItem(nodo.getChildText("stkItem"));
     	detalle.setSlsPrice(nodo.getChildText("slsPrice"));
     	detalle.setSlsPriceSale(nodo.getChildText("slsPriceSale"));
     	detalle.setStdCostPen(nodo.getChildText("stdCostPen"));
     	detalle.setDescrInventory(nodo.getChildText("descrInventory"));
     	detalle.setQty(nodo.getChildText("qty"));
     	detalle.setUserId(nodo.getChildText("userId"));

		return detalle;
	}
	
}
